package com.yanqu.road.server.manager.activity.zhenhuan;

import com.yanqu.road.dao.impl.activity.zhenhuan.thirdProcess.CrossZhenHuanThirdProcessBanquetDataDaoImpl;
import com.yanqu.road.dao.impl.activity.zhenhuan.thirdProcess.CrossZhenHuanThirdProcessBanquetUserDataDaoImpl;
import com.yanqu.road.dao.impl.activity.zhenhuan.thirdProcess.CrossZhenHuanThirdProcessUserDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.zhenhuan.thirdProcess.CrossZhenHuanThirdProcessBanquetData;
import com.yanqu.road.entity.activity.zhenhuan.thirdProcess.CrossZhenHuanThirdProcessBanquetUserData;
import com.yanqu.road.entity.activity.zhenhuan.thirdProcess.CrossZhenHuanThirdProcessUserData;
import com.yanqu.road.entity.enums.activity.zhenhuan.eZhenHuanThirdProcessBanquetStateType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.player.CrossUserBaseInfo;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.rank.cross.CrossUserRank;
import com.yanqu.road.logic.activity.zhenhuan.ZhenHuanThirdProcessConfig;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.activity.ZhenHuanProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.activity.ActivityMgr;
import com.yanqu.road.server.manager.activity.ActivityRankMgr;
import com.yanqu.road.server.manager.npc.CrossNpcUserMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.MapHelper;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.lang.reflect.Method;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 甄嬛三阶段
 */
public class CrossZhenHuanThirdProcessActivity {

    private static Logger logger = LogManager.getLogger(CrossZhenHuanThirdProcessActivity.class.getName());

    protected RandomHelper randomHelper = new RandomHelper();

    private Map<Integer, Object> lockMap = new ConcurrentHashMap<>();
    private Map<Long, Object> userLockMap = new ConcurrentHashMap<>();
    private List<CrossZhenHuanThirdProcessBanquetUserData> needInsertBanquetUserDataList = new ArrayList<>();

    /**
     * 活动数据
     */
    private int activityId;

    /**
     * 用户数据
     */
    private Map<Long, CrossZhenHuanThirdProcessUserData> userDataMap = new ConcurrentHashMap<>();

    /**
     * 宴会桌， 用户id，宴会id，数据
     */
    private Map<Long, LinkedList<CrossZhenHuanThirdProcessBanquetData>> userBanquetListMap = new ConcurrentHashMap<>();
    private Map<Integer, CrossZhenHuanThirdProcessBanquetData> banquetDataMap = new ConcurrentHashMap<>();

    /**
     * 最大宴会编号
     */
    private AtomicInteger maxBanquetId = new AtomicInteger(0);

    /**
     * 待同步的开宴列表
     */
    private List<CrossZhenHuanThirdProcessBanquetData> syncOpenList = new ArrayList<>();

    /**
     * 待同步的入宴列表
     */
    private Map<Integer, Map<Integer, Long>> syncJoinerMap = new ConcurrentHashMap<>();
    /**
     * 待移出内存的宴会
     */
    private List<CrossZhenHuanThirdProcessBanquetData> waitRemoveBanquetList = new ArrayList<>();

    /**
     * 宴会锁
     *
     * @param banquetId 宴会id
     */
    private Object getBanquetLock(int banquetId) {
        if (!lockMap.containsKey(banquetId)) {
            synchronized (lockMap) {
                if (!lockMap.containsKey(banquetId))
                    lockMap.put(banquetId, new Object());
            }
        }
        return lockMap.get(banquetId);
    }

    /**
     * 玩家锁
     *
     * @return
     */
    private Object getUserLock(long userId) {
        if (!userLockMap.containsKey(userId)) {
            synchronized (userLockMap) {
                if (!userLockMap.containsKey(userId)) {
                    userLockMap.put(userId, new Object());
                }
            }
        }
        return userLockMap.get(userId);
    }

    public int getActivityId() {
        return activityId;
    }

    public CrossZhenHuanThirdProcessActivity(ActivityInfo activityInfo) {
        this.activityId = activityInfo.getActivityId();
        loadDb();
    }

    public void loadDb() {
        //玩家数据
        Map<Long, CrossZhenHuanThirdProcessUserData> tempUserDataMap = new CrossZhenHuanThirdProcessUserDataDaoImpl().getCrossZhenHuanThirdProcessUserDataMap(activityId);
        //宴会数据
        List<CrossZhenHuanThirdProcessBanquetData> tempBanquetDataList = new CrossZhenHuanThirdProcessBanquetDataDaoImpl().getCrossZhenHuanThirdProcessBanquetDataList(activityId);
        //宴会入宴者数据
        Map<Integer, Map<Long, CrossZhenHuanThirdProcessBanquetUserData>> tempBanquetUserDataList = new CrossZhenHuanThirdProcessBanquetUserDataDaoImpl().getCrossZhenHuanThirdProcessBanquetUserDataMap(activityId);

        Map<Integer, CrossZhenHuanThirdProcessBanquetData> tempBanquetDataMap = new ConcurrentHashMap<>();
        Map<Long, LinkedList<CrossZhenHuanThirdProcessBanquetData>> tempUserBanquetListMap = new ConcurrentHashMap<>();
        // 取一下最大的宴会id
        int tempMaxBanquetId = 0;

        for (CrossZhenHuanThirdProcessBanquetData banquetData : tempBanquetDataList) {
            LinkedList<CrossZhenHuanThirdProcessBanquetData> dataList = tempUserBanquetListMap.get(banquetData.getUserId());
            if (dataList == null) {
                dataList = new LinkedList<>();
                tempUserBanquetListMap.put(banquetData.getUserId(), dataList);
            }
            dataList.addLast(banquetData);

            if (isValidBanquet(banquetData)) {//无效宴会不加载
                //宴会注入入宴者MAP
                Map<Long, CrossZhenHuanThirdProcessBanquetUserData> joinerMap = tempBanquetUserDataList.get(banquetData.getBanquetId());
                if (joinerMap != null) {
                    banquetData.setJoinerMap(joinerMap);
                }

                tempBanquetDataMap.put(banquetData.getBanquetId(), banquetData);
            }
            tempMaxBanquetId = Math.max(tempMaxBanquetId, banquetData.getBanquetId());
        }

        this.userDataMap = tempUserDataMap;
        this.banquetDataMap = tempBanquetDataMap;
        this.userBanquetListMap = tempUserBanquetListMap;
        this.maxBanquetId = new AtomicInteger(tempMaxBanquetId);

        for (Long userId : this.userBanquetListMap.keySet()) {
            checkUserEndBanquet(userId);
        }
    }

    /**
     * 存储
     */
    public void save() {
        //玩家数据
        for (CrossZhenHuanThirdProcessUserData userData : this.userDataMap.values()) {
            if (userData.isInsertOption()) {
                new CrossZhenHuanThirdProcessUserDataDaoImpl().add(userData);
            } else if (userData.isUpdateOption()) {
                new CrossZhenHuanThirdProcessUserDataDaoImpl().update(userData);
            }
        }
        //玩家宴会数据
        List<CrossZhenHuanThirdProcessBanquetData> allBanquetDataList = getAllBanquetDataList();
        for (CrossZhenHuanThirdProcessBanquetData banquetData : allBanquetDataList) {
//            //存储入宴玩家,赴宴玩家不会变动一次性插入就可以了
//            for (CrossZhenHuanThirdProcessBanquetUserData joiner : banquetData.getJoinerMap().values()) {
//                if (joiner.isInsertOption()) {
//                    new CrossZhenHuanThirdProcessBanquetUserDataDaoImpl().add(joiner);
//                }
//            }

            if (banquetData.isInsertOption()) {
                new CrossZhenHuanThirdProcessBanquetDataDaoImpl().add(banquetData);
            } else if (banquetData.isUpdateOption()) {
                new CrossZhenHuanThirdProcessBanquetDataDaoImpl().update(banquetData);
            }
        }

        List<CrossZhenHuanThirdProcessBanquetUserData> saveJoinerList = new ArrayList<>();
        synchronized (needInsertBanquetUserDataList){
            saveJoinerList.addAll(needInsertBanquetUserDataList);
            needInsertBanquetUserDataList.clear();
        }

        new CrossZhenHuanThirdProcessBanquetUserDataDaoImpl().batchAdd(saveJoinerList);

        List<CrossZhenHuanThirdProcessBanquetData> saveBanquetList = new ArrayList<>();
        synchronized (waitRemoveBanquetList) {
            saveBanquetList.addAll(waitRemoveBanquetList);
            waitRemoveBanquetList.clear();
        }
        for (CrossZhenHuanThirdProcessBanquetData banquetData : saveBanquetList) {
            if (banquetData.isInsertOption()) {
                new CrossZhenHuanThirdProcessBanquetDataDaoImpl().add(banquetData);
            } else if (banquetData.isUpdateOption()) {
                new CrossZhenHuanThirdProcessBanquetDataDaoImpl().update(banquetData);
            }
        }
    }

    public List<CrossZhenHuanThirdProcessBanquetData> getAllBanquetDataList() {
        List<CrossZhenHuanThirdProcessBanquetData> dataList = new ArrayList<>();
        synchronized (banquetDataMap) {
            dataList.addAll(banquetDataMap.values());
        }
        return dataList;
    }

    /**
     * 获取用户数据
     *
     * @param userId 用户id
     */
    public CrossZhenHuanThirdProcessUserData getUserData(long userId) {
        return userDataMap.get(userId);
    }

    /**
     * 初始化用户数据
     *
     * @param userId 用户id
     */
    public CrossZhenHuanThirdProcessUserData initUserData(long userId, BigInteger value, String param, long lastUpdateTime) {
        boolean addFlag = false;
        if (!userDataMap.containsKey(userId)) {
            synchronized (userDataMap) {
                if (!userDataMap.containsKey(userId)) {
                    CrossZhenHuanThirdProcessUserData userData = new CrossZhenHuanThirdProcessUserData(activityId, userId);
                    userData.setLevel(value.intValue());
                    userData.setPrestige(Long.valueOf(param));
                    userData.setLastUpdateTime(lastUpdateTime);
                    userData.setBanquetNum(0);
                    userData.setInsertOption();
                    userDataMap.put(userId, userData);
                    addFlag = true;
                }
            }
        }
        if (addFlag) {
            // 位置排序一下
            rankToPos();
        }
        return userDataMap.get(userId);
    }

    /**
     * 位置排序
     */
    private void rankToPos() {
        List<CrossZhenHuanThirdProcessUserData> userList = new ArrayList<>(userDataMap.values());
        userList.sort((o1, o2) -> {
            int compare = Integer.compare(o2.getLevel(), o1.getLevel());
            if (compare != 0) {
                return compare;
            }
            compare = Long.compare(o2.getPrestige(), o1.getPrestige());
            if (compare != 0) {
                return compare;
            }
            return Long.compare(o1.getLastUpdateTime(), o2.getLastUpdateTime());
        });
        int rank = 1;
        for (CrossZhenHuanThirdProcessUserData userData : userList) {
            userData.setPos(rank++);
        }
    }

    /**
     * 开宴会
     *
     * @param serverId 区服id
     * @param userId   开宴者Id
     * @param openItemId   宴会类型（开宴道具ID）
     */
    public int openBanquetByCmd(long serverId, long userId, int openItemId) {
        CrossZhenHuanThirdProcessUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_ZHENHUAN_THIRD_PROCESS_USER_NOT_FOUND;
        }
        synchronized (getUserLock(userId)) {
            // 判断下能否开席
            if (!canOpenBanquet(userId)) {
                return GameErrorCode.E_ZHENHUAN_THIRD_PROCESS_IS_OPEN_BANQUET;
            }
            // 开席
            CrossZhenHuanThirdProcessBanquetData banquetData = initBanquet(userId, openItemId);

            //记录开宴总次数
            userData.setBanquetNum(userData.getBanquetNum() + 1);

            // 加入待同步列表
            addSyncOpenList(banquetData);

            // 回游戏服
            ZhenHuanProto.CrossZhenHuanThirdProcessOpenBanquetRespMsg.Builder respMsg = ZhenHuanProto.CrossZhenHuanThirdProcessOpenBanquetRespMsg.newBuilder();
            respMsg.setRet(0);
            respMsg.setBanquetId(banquetData.getBanquetId());
            // 获取下当前的总开宴次数同步到区服成就
            respMsg.setBanquetTimes(getUserBanquetCount(userId));
            respMsg.setOpenItemId(openItemId);
            MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(Protocol.S_ZHENHUAN_THIRD_PROCESS_OPEN_BANQUET_FROM_CROSS, respMsg));
        }

        return 0;
    }

    /**
     * 加入待同步列表
     * @param banquetData 宴会信息
     */
    public void addSyncOpenList(CrossZhenHuanThirdProcessBanquetData banquetData) {
        if (banquetData == null) {
            return;
        }
        synchronized (syncOpenList) {
            syncOpenList.add(banquetData);
        }
    }

    /**
     * 初始化宴会
     *
     * @param userId 用户id
     */
    private CrossZhenHuanThirdProcessBanquetData initBanquet(long userId, int openItemId) {
        CrossZhenHuanThirdProcessUserData userData = getUserData(userId);
        if (userData == null) {
            return null;
        }

        CrossZhenHuanThirdProcessBanquetData banquetData = new CrossZhenHuanThirdProcessBanquetData(activityId, userId, maxBanquetId.incrementAndGet(), openItemId);
        banquetData.setScore(0);
        banquetData.setStartTime(System.currentTimeMillis());
        banquetData.setInsertOption();

        banquetDataMap.put(banquetData.getBanquetId(), banquetData);

        synchronized (getUserLock(userId)) {
            LinkedList<CrossZhenHuanThirdProcessBanquetData> dataList = userBanquetListMap.get(userId);
            if (dataList == null) {
                dataList = new LinkedList<>();
                userBanquetListMap.put(userId, dataList);
            }
            dataList.addLast(banquetData);
        }

        return banquetData;
    }

    /**
     * 判断下能否开席
     *
     * @param userId 用户id
     */
    private boolean canOpenBanquet(long userId) {
//        int userBanquetCount = getUserBanquetCount(userId);
//        if (userBanquetCount >= 1000){//同时开席上限
//            return false;
//        }
        // 在开的最新一场宴会要结算积分后才能开席
        CrossZhenHuanThirdProcessBanquetData userOpenBanquet = getUserLastValidOpenBanquet(userId);
        if (userOpenBanquet == null) {
            return true;
        }
        if (userOpenBanquet.getBanquetState() == eZhenHuanThirdProcessBanquetStateType.Settle.getValue()) {
            return true;
        }
        return false;
    }

    /**
     * 加入宴会
     *
     * @param serverId     区服id
     * @param userId       用户id
     * @param targetUserId 谁的宴会
     * @param banquetId    宴会id
     */
    public int joinBanquetByCmd(long serverId, long userId, long targetUserId, int banquetId) {
        ZhenHuanThirdProcessConfig config = getConfig();
        if (config == null) {
            return GameErrorCode.E_ZHENHUAN_THIRD_PROCESS_CONFIG_NOT_FOUND;
        }
        CrossZhenHuanThirdProcessBanquetData banquetData = getBanquetData(targetUserId, banquetId);
        if (banquetData == null) {
            return GameErrorCode.E_ZHENHUAN_THIRD_PROCESS_BANQUET_NOT_FOUND;
        }
        if (!isValidBanquet(banquetData)) {
            return GameErrorCode.E_ZHENHUAN_THIRD_PROCESS_BANQUET_NOT_VALID;
        }
        // 加入宴会
        int flag = joinBanquet(banquetId, targetUserId, userId);
        if (flag == 0) {
            String joinReward = config.randomJoinReward(banquetData.getOpenItemId()).toHelperString();
            ZhenHuanProto.CrossZhenHuanThirdProcessJoinBanquetRespMsg.Builder respMsg = ZhenHuanProto.CrossZhenHuanThirdProcessJoinBanquetRespMsg.newBuilder();
            respMsg.setRet(0);
            respMsg.setReward(joinReward);

            CrossZhenHuanThirdProcessBanquetUserData joiner = banquetData.getJoiner(userId);
            if (joiner != null) {
                ZhenHuanProto.CrossZhenHuanThirdProcessJoinBanquetTemp.Builder joinTemp = ZhenHuanProto.CrossZhenHuanThirdProcessJoinBanquetTemp.newBuilder();
                joinTemp.setBanquetId(banquetId);
                joinTemp.setReward(joinReward);
                joinTemp.setPos(joiner.getPos());
                respMsg.addJoinList(joinTemp);
            }

            MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(Protocol.S_ZHENHUAN_THIRD_PROCESS_JOIN_BANQUET_FROM_CROSS, respMsg));
            return 0;
        } else {
            return flag;
        }
    }

    /**
     * 加入宴会-一键
     *
     * @param serverId     区服id
     * @param userId       用户id
     * @param targetUserId 谁的宴会
     */
    public int joinBanquetOneKeyByCmd(long serverId, long userId, long targetUserId) {
        ZhenHuanThirdProcessConfig config = getConfig();
        if (config == null) {
            return GameErrorCode.E_ZHENHUAN_THIRD_PROCESS_CONFIG_NOT_FOUND;
        }
        List<ZhenHuanProto.CrossZhenHuanThirdProcessJoinBanquetTemp> joinList = new ArrayList<>();
        //宴会列表
        List<CrossZhenHuanThirdProcessBanquetData> banquetList = this.getBanquetDataList(targetUserId, true);
        Property reward = new Property();
        for (CrossZhenHuanThirdProcessBanquetData banquetData : banquetList) {
            // 加入宴会
            if (banquetData.getBanquetState() != eZhenHuanThirdProcessBanquetStateType.End.getValue()) {
                //入宴一次的奖励
                Property onceReward = config.randomJoinReward(banquetData.getOpenItemId());
                //入宴
                int flag = joinBanquet(banquetData.getBanquetId(), targetUserId, userId);
                if (flag == 0) {
                    reward.addProperty(onceReward);

                    CrossZhenHuanThirdProcessBanquetUserData joiner = banquetData.getJoiner(userId);
                    if (joiner != null) {
                        ZhenHuanProto.CrossZhenHuanThirdProcessJoinBanquetTemp.Builder joinTemp = ZhenHuanProto.CrossZhenHuanThirdProcessJoinBanquetTemp.newBuilder();
                        joinTemp.setBanquetId(banquetData.getBanquetId());
                        joinTemp.setPos(joiner.getPos());
                        joinTemp.setReward(onceReward.toHelperString());
                        joinList.add(joinTemp.build());
                    }
                }
            }
        }
        ZhenHuanProto.CrossZhenHuanThirdProcessJoinBanquetRespMsg.Builder respMsg = ZhenHuanProto.CrossZhenHuanThirdProcessJoinBanquetRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setReward(PropertyHelper.parsePropertyToString(reward));
        respMsg.addAllJoinList(joinList);
        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(Protocol.S_ZHENHUAN_THIRD_PROCESS_JOIN_BANQUET_FROM_CROSS, respMsg));
        return 0;
    }

    /**
     * 加入宴会
     *
     * @param banquetId    宴会id
     * @param targetUserId 宴会开启者
     * @param userId       加入的用户
     */
    public int joinBanquet(int banquetId, long targetUserId, long userId) {
        ZhenHuanThirdProcessConfig config = getConfig();
        // 上个锁
        int pos = 0;
        CrossZhenHuanThirdProcessBanquetData banquetData = getBanquetData(targetUserId, banquetId);
        if (banquetData == null) {
            return GameErrorCode.E_ZHENHUAN_THIRD_PROCESS_BANQUET_NOT_VALID;
        }
        synchronized (getBanquetLock(banquetId)) {
            if (!isValidBanquet(banquetData)) {
                return GameErrorCode.E_ZHENHUAN_THIRD_PROCESS_BANQUET_NOT_VALID;
            }
            Map<Long, CrossZhenHuanThirdProcessBanquetUserData> joinerMap = banquetData.getJoinerMap();
            if (joinerMap.containsKey(userId)) {
                return GameErrorCode.E_ZHENHUAN_THIRD_PROCESS_BANQUET_BANQUET_IS_JOIN;
            }

            //添加入宴者
            CrossZhenHuanThirdProcessBanquetUserData joinerData = banquetData.addJoiner(userId);
            if (joinerData != null) {
                pos = joinerData.getPos();

                synchronized (needInsertBanquetUserDataList) {
                    needInsertBanquetUserDataList.add(joinerData);
                }
            }

            if(banquetData.getJoinerMap().size() <= config.getCelebrationJoinPeopleMax(banquetData.getOpenItemId())){
                // 计算下积分
                long addScore = Math.min(config.getCelebrationScoreMax(banquetData.getOpenItemId()), config.getCelebrationJoinScore(banquetData.getOpenItemId()) * banquetData.getJoinerMap().size());
                // 该宴会增加的积分
                banquetData.setScore(addScore);
            }
        }
        // 加到同步列表
        addSyncJoinerMap(banquetId, pos, userId);
        return 0;
    }

    /**
     * 入宴用户加到待同步列表
     *
     * @param banquetId 宴会id
     * @param pos       位置
     * @param userId    入宴id
     */
    private void addSyncJoinerMap(int banquetId, int pos, long userId) {
        synchronized (syncJoinerMap) {
            Map<Integer, Long> map = syncJoinerMap.getOrDefault(banquetId, new ConcurrentHashMap<>());
            map.put(pos, userId);
            syncJoinerMap.put(banquetId, map);
        }
    }

    /**
     * 获取宴会信息
     *
     * @param userId    宴会开启者
     * @param banquetId 宴会id
     */
    public CrossZhenHuanThirdProcessBanquetData getBanquetData(long userId, int banquetId) {
        CrossZhenHuanThirdProcessBanquetData banquetData = banquetDataMap.get(banquetId);
        if (banquetData != null && banquetData.getUserId() == userId) {
            return banquetData;
        }
        return null;
    }

    /**
     * 获取用户的宴会列表
     *
     * @param userId 宴会开启者
     */
    public List<CrossZhenHuanThirdProcessBanquetData> getBanquetDataList(long userId, int limit, boolean isNeedValid) {
        List<CrossZhenHuanThirdProcessBanquetData> dataList = new ArrayList<>();
        CrossZhenHuanThirdProcessUserData userData = getUserData(userId);
        if (userData == null) {
            return dataList;
        }

        synchronized (getUserLock(userId)) {
            //userBanquetDataList倒叙
            LinkedList<CrossZhenHuanThirdProcessBanquetData> userBanquetDataList = userBanquetListMap.get(userId);
            if (userBanquetDataList == null) {
                return dataList;
            }
            for (int i = userBanquetDataList.size() - 1; i >= 0; i--) {
                CrossZhenHuanThirdProcessBanquetData banquetData = userBanquetDataList.get(i);
                if (isNeedValid) {
                    if (isValidBanquet(banquetData)) {
                        dataList.add(banquetData);
                    }
                } else {
                    dataList.add(banquetData);
                }

                if (dataList.size() >= limit) {
                    break;
                }
            }
        }
        return dataList;
    }

    /**
     * 获取配置
     */
    public ZhenHuanThirdProcessConfig getConfig() {
        return CrossZhenHuanConfigMgr.getThirdProcessConfig(activityId);
    }

    /**
     * 获取用户的宴会列表
     *
     * @param userId 宴会开启者
     */
    public List<CrossZhenHuanThirdProcessBanquetData> getBanquetDataList(long userId, boolean isNeedValid) {
        ZhenHuanThirdProcessConfig config = getConfig();
        if (config == null) {
            return new ArrayList<>();
        }
        // 取前n个
        return getBanquetDataList(userId, config.getJoinNumberMax(), isNeedValid);
    }

    /**
     * 判断宴会是否有效
     *
     * @param banquetData 宴会信息
     * @return boolean  true 有效 false 无效
     */
    public boolean isValidBanquet(CrossZhenHuanThirdProcessBanquetData banquetData) {
        ZhenHuanThirdProcessConfig config = getConfig();
        if (config == null) {
            return false;
        }
        if (banquetData == null) {
            return false;
        }
        return banquetData.getBanquetState() != eZhenHuanThirdProcessBanquetStateType.End.getValue();
    }

    /**
     * 拉取用户宴会列表
     *
     * @param serverId     区服id
     * @param userId       用户id
     * @param targetUserId 谁的宴会
     */
    public int getUserBanquetListByCmd(long serverId, long userId, long targetUserId) {
        ZhenHuanProto.ZhenHuanThirdProcessGetUserBanquetListRespMsg.Builder respMsg = ZhenHuanProto.ZhenHuanThirdProcessGetUserBanquetListRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setTargetUserId(targetUserId);
        List<CrossZhenHuanThirdProcessBanquetData> banquetDataList = getBanquetDataList(targetUserId, false);
        for (CrossZhenHuanThirdProcessBanquetData banquetData : banquetDataList) {
            ZhenHuanProto.ZhenHuanThirdProcessBanquetTempMsg.Builder banquetTemp = ZhenHuanProto.ZhenHuanThirdProcessBanquetTempMsg.newBuilder();
            banquetTemp.setBanquetId(banquetData.getBanquetId());
            banquetTemp.setStartTime(banquetData.getStartTime());
            banquetTemp.setUserCount(banquetData.getJoinerMap().size());
            banquetTemp.setScore(banquetData.getScore());
            // 是否已加入该宴会
            banquetTemp.setJoined(banquetData.getJoinerMap().containsKey(userId));
            banquetTemp.setOpenItemId(banquetData.getOpenItemId());
            respMsg.addBanquetList(banquetTemp);
        }
        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(Protocol.U_ZHENHUAN_THIRD_PROCESS_GET_USER_BANQUET_LIST, respMsg));
        return 0;
    }

    /**
     * 拉取宴会成员列表
     *
     * @param serverId     区服id
     * @param userId       用户id
     * @param targetUserId 宴会开启者
     * @param banquetId    宴会id
     * @param page         第几页
     * @param num          每页多少人
     */
    public int getBanquetJoinerListByCmd(long serverId, long userId, long targetUserId, int banquetId, int page, int num) {
        if (page <= 0) {
            page = 1;
        }
        if (num <= 0 || num > 100) {
            num = 100;
        }
        CrossZhenHuanThirdProcessBanquetData banquetData = getBanquetData(targetUserId, banquetId);
        if (banquetData == null) {
            return GameErrorCode.E_ZHENHUAN_THIRD_PROCESS_BANQUET_NOT_FOUND;
        }
        Map<Long, CrossZhenHuanThirdProcessBanquetUserData> tempJoinerMap = new LinkedHashMap<>();
        synchronized (getBanquetLock(banquetId)) {
            tempJoinerMap = new HashMap<>(banquetData.getJoinerMap());
        }

        ZhenHuanProto.ZhenHuanThirdProcessGetBanquetJoinerListRespMsg.Builder respMsg = ZhenHuanProto.ZhenHuanThirdProcessGetBanquetJoinerListRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setActivityId(activityId);
        respMsg.setTargetUserId(targetUserId);
        respMsg.setBanquetId(banquetId);
        respMsg.setUserCount(tempJoinerMap.size());
        respMsg.setBanquetState(banquetData.getBanquetState());

        //分页
        Map<Long, CrossZhenHuanThirdProcessBanquetUserData> joinerMap = MapHelper.getLinkedMapPage(tempJoinerMap, page, num);
        for (CrossZhenHuanThirdProcessBanquetUserData joiner : joinerMap.values()) {
            int pos = joiner.getPos();
            long tempUserId = joiner.getJoinUserId();
            UserBaseInfo userBaseInfo = getUserBaseInfo(tempUserId);
            if (userBaseInfo == null) {
                continue;
            }
            ZhenHuanProto.ZhenHuanThirdProcessBanquetJoinerTempMsg.Builder userTemp = ZhenHuanProto.ZhenHuanThirdProcessBanquetJoinerTempMsg.newBuilder();
            userTemp.setPos(pos);
            userTemp.setUserId(tempUserId);
            userTemp.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            respMsg.addJoinerList(userTemp);
        }
        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(Protocol.U_ZHENHUAN_THIRD_PROCESS_GET_BANQUET_JOINER_LIST, respMsg));
        return 0;
    }

    /**
     * 分页获取
     *
     * @param joinerMap 参加的人员列表
     * @param page      第几页
     * @param num       每页多少人
     */
    private Map<Integer, Long> getPageJoinMap(Map<Integer, Long> joinerMap, int page, int num) {
        Map<Integer, Long> resMap = new ConcurrentHashMap<>();
        int count = joinerMap.size();
        int index = (page - 1) * num;
        int resCount = 0;
        for (; index < count + num; index++) {
            if (resCount++ == num) {
                break;
            }
            if (joinerMap.size() > index) {
                //joinerMap的key是位置，按照1开始
                Long userId = joinerMap.get(index + 1);
                resMap.put(index, userId);
            } else {
                break;
            }
        }
        return resMap;
    }

    /**
     * 调试定时器
     */
    public void debugTask() {
        logger.info("甄嬛三阶段,活动id:{}", activityId);
    }

    /**
     * 宴会同步定时器
     */
    public void banquetSyncTask() {
        // 开宴同步
        syncBanquetOpen();
        // 入宴同步
        syncBanquetJoin();
    }

    /**
     * 入宴同步
     */
    private void syncBanquetJoin() {
        Map<Integer, Map<Integer, Long>> map;
        synchronized (syncJoinerMap) {
            map = new ConcurrentHashMap<>(syncJoinerMap);
            syncJoinerMap.clear();
        }
        if (map.isEmpty()) {
            return;
        }
        for (Map.Entry<Integer, Map<Integer, Long>> entry : map.entrySet()) {
            Integer banquetId = entry.getKey();
            Map<Integer, Long> posMap = entry.getValue();

            // 拉一下需要同步的玩家
            ZhenHuanProto.ZhenHuanThirdProcessBanquetJoinSyncMsg.Builder syncMsg = ZhenHuanProto.ZhenHuanThirdProcessBanquetJoinSyncMsg.newBuilder();
            syncMsg.setBanquetId(banquetId);
            for (Map.Entry<Integer, Long> posEntry : posMap.entrySet()) {
                Integer pos = posEntry.getKey();
                Long userId = posEntry.getValue();
                UserBaseInfo userBaseInfo = getUserBaseInfo(userId);
                if (userBaseInfo == null) {
                    continue;
                }
                ZhenHuanProto.ZhenHuanThirdProcessBanquetJoinerTempMsg.Builder joinerTemp = ZhenHuanProto.ZhenHuanThirdProcessBanquetJoinerTempMsg.newBuilder();
                joinerTemp.setPos(pos);
                joinerTemp.setUserId(userId);
                joinerTemp.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                syncMsg.addJoinerList(joinerTemp);
            }
            // 同步给入宴的用户
            MessageHelper.sendPacketToAll(Protocol.U_ZHENHUAN_THIRD_PROCESS_BANQUET_JOIN_SYNC, syncMsg, getBanquetJoinerList(banquetId));
        }

    }

    /**
     * 获取宴会信息
     *
     * @param banquetId 宴会id
     */
    public CrossZhenHuanThirdProcessBanquetData getBanquetData(int banquetId) {
        return banquetDataMap.get(banquetId);
    }

    /**
     * 获取宴会成员列表
     *
     * @param banquetId 宴会id
     */
    public List<Long> getBanquetJoinerList(int banquetId) {
        CrossZhenHuanThirdProcessBanquetData banquetData = getBanquetData(banquetId);
        if (banquetData == null) {
            return new ArrayList<>();
        } else {
            synchronized (getBanquetLock(banquetId)) {
                return new ArrayList<>(banquetData.getJoinerMap().keySet());
            }
        }
    }

    /**
     * 开宴同步
     */
    private void syncBanquetOpen() {
        List<CrossZhenHuanThirdProcessBanquetData> list;
        synchronized (syncOpenList) {
            list = new ArrayList<>(syncOpenList);
            syncOpenList.clear();
        }
        if (list.isEmpty()) {
            return;
        }
        ZhenHuanThirdProcessConfig config = getConfig();
        if (config == null) {
            return;
        }
        ZhenHuanProto.ZhenHuanThirdProcessOpenBanquetNoticeSyncMsg.Builder syncMsg = ZhenHuanProto.ZhenHuanThirdProcessOpenBanquetNoticeSyncMsg.newBuilder();
        syncMsg.setActivityId(activityId);
        for (CrossZhenHuanThirdProcessBanquetData banquetData : list) {
            UserBaseInfo userBaseInfo = getUserBaseInfo(banquetData.getUserId());
            if (userBaseInfo == null) {
                continue;
            }
            ZhenHuanProto.ZhenHuanThirdProcessBanquetOpenTempMsg.Builder banquetTemp = ZhenHuanProto.ZhenHuanThirdProcessBanquetOpenTempMsg.newBuilder();
            banquetTemp.setUserId(banquetData.getUserId());
            banquetTemp.setBanquetId(banquetData.getBanquetId());
            banquetTemp.setStartTime(banquetData.getStartTime());
            banquetTemp.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            banquetTemp.setBanquetTimes(getUserBanquetCount(banquetData.getUserId()));
            banquetTemp.setOpenItemId(banquetData.getOpenItemId());
            syncMsg.addBanquetList(banquetTemp);
        }
        // 同步到各个区服
        for (Long serverId : config.getActivityInfo().getServerIdList()) {
            YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.S_ZHENHUAN_THIRD_PROCESS_OPEN_BANQUET_NOTICE_FROM_CROSS, syncMsg);
            MessageHelper.sendPacket(serverId, 0, pbMsg);
        }

    }

    /**
     * 宴会逻辑定时器
     */
    public void banquetLogicTask() {
        Set<Long> banquetEndUserIdSet = new HashSet<>();//需要检查已结束宴会数量的玩家

        List<CrossZhenHuanThirdProcessBanquetData> allBanquetDataList = getAllBanquetDataList();
        for (CrossZhenHuanThirdProcessBanquetData banquetData : allBanquetDataList) {
            if (banquetData.getBanquetState() == eZhenHuanThirdProcessBanquetStateType.End.getValue()) {
                // 已结束了不处理
                continue;
            }
            // 宴会结算进程
            banquetSettleProcess(banquetData);
            // 宴会结束进程
            banquetEndProcess(banquetData);

            banquetEndUserIdSet.add(banquetData.getUserId());
        }

        for (Long userId : banquetEndUserIdSet) {
            //玩家身上最多存50个已结束的
            checkUserEndBanquet(userId);
        }
    }

    public void checkUserEndBanquet(long userId) {
        CrossZhenHuanThirdProcessUserData userData = getUserData(userId);
        if (userData == null) {
            return;
        }

        ZhenHuanThirdProcessConfig config = getConfig();
        if (config == null) {
            return;
        }

        LinkedList<CrossZhenHuanThirdProcessBanquetData> userBanquetDataList = userBanquetListMap.get(userId);
        if (userBanquetDataList == null) {
            return;
        }

        int numLimit = config.getJoinNumberMax();//保留数和玩家可一次性赴宴的一致
        if (userBanquetDataList.size() <= numLimit) {
            return;
        }
        List<CrossZhenHuanThirdProcessBanquetData> checkList = new ArrayList<>();
        synchronized (getUserLock(userId)) {
            checkList.addAll(userBanquetDataList);
        }

        int searchAmount = 0;
        for (int i = checkList.size() - 1; i >= 0; i--) {
            CrossZhenHuanThirdProcessBanquetData banquetData = checkList.get(i);
            if (banquetData.getBanquetState() != eZhenHuanThirdProcessBanquetStateType.End.getValue()) {
                // 未结束了不处理
                continue;
            }
            searchAmount++;
            if (searchAmount > numLimit) {
                banquetRemoveMemory(banquetData);

                synchronized (waitRemoveBanquetList) {
                    waitRemoveBanquetList.add(banquetData);
                }
            }
        }
    }

    /**
     * 宴会结算
     */
    private void banquetSettleProcess(CrossZhenHuanThirdProcessBanquetData banquetData) {
        ZhenHuanThirdProcessConfig config = getConfig();
        if (config == null) {
            return;
        }
        if (banquetData == null) {
            return;
        }
        // 检测下是否满足结算条件
        if (banquetData.getBanquetState() == eZhenHuanThirdProcessBanquetStateType.End.getValue()) {
            // 宴会已结束
            return;
        }
        if (banquetData.getBanquetState() == eZhenHuanThirdProcessBanquetStateType.Settle.getValue()) {
            // 宴会已结算
            return;
        }
        CrossZhenHuanThirdProcessUserData userData = getUserData(banquetData.getUserId());
        if (userData == null) {
            // 用户没了，理论上不存在
            return;
        }
        long nowTime = System.currentTimeMillis();
        synchronized (getBanquetLock(banquetData.getBanquetId())) {
            // 检测下是否满足结算条件
            if (banquetData.getBanquetState() == eZhenHuanThirdProcessBanquetStateType.End.getValue()) {
                // 宴会已结束
                return;
            }
            if (banquetData.getBanquetState() == eZhenHuanThirdProcessBanquetStateType.Settle.getValue()) {
                // 宴会已结算
                return;
            }
            // 时间到了，人数达到要求了，提前结束
            if (nowTime >= banquetData.getStartTime() + config.getEnergyItemTime(banquetData.getOpenItemId()) * DateHelper.SECOND_MILLIONS
                    || banquetData.getJoinerMap().size() >= config.getCelebrationJoinPeopleMax(banquetData.getOpenItemId())) {
                // 宴会达到结算条件
                banquetData.setBanquetState(eZhenHuanThirdProcessBanquetStateType.Settle.getValue());
                // 给开宴者发积分
                // 计算下积分
                long addScore = Math.min(config.getCelebrationScoreMax(banquetData.getOpenItemId()), config.getCelebrationJoinScore(banquetData.getOpenItemId()) * banquetData.getJoinerMap().size());
                // 该宴会增加的积分
                banquetData.setScore(addScore);

                userData.setScore(userData.getScore() + addScore);

                // 更新下跨服榜单
                CrossUserRank crossUserRank = new CrossUserRank();
                crossUserRank.setUserId(userData.getUserId());
                crossUserRank.setValue(BigInteger.valueOf(userData.getScore()));
                crossUserRank.setType(activityId);
                crossUserRank.setBigRankType(eGamePlayerEventType.ZhenHuanThirdProcessRank.getValue());
                UserBaseInfo userBaseInfo = getUserBaseInfo(userData.getUserId());
                if (userBaseInfo != null) {
                    crossUserRank.setUserBaseInfo(userBaseInfo);
                }
                if (ActivityMgr.activityInTime(config.getActivityInfo())) {
                    ActivityRankMgr.changeActivityNewRank(activityId, eGamePlayerEventType.ZhenHuanThirdProcessRank.getValue(), crossUserRank);
                }

                // 分数同步到游戏服
                notifyBanquetScoreChange(userData.getUserId(), addScore, userData.getScore(), banquetData.getBanquetId());
            }
        }
    }

    /**
     * 同步积分变动
     *
     * @param addScore   增加的积分
     * @param totalScore 总积分
     */
    private void notifyBanquetScoreChange(long userId, long addScore, long totalScore, int banquetId) {
        UserBaseInfo userBaseInfo = getUserBaseInfo(userId);
        if (userBaseInfo == null) {
            return;
        }
        ZhenHuanProto.CrossZhenHuanThirdProcessBanquetScoreNotifyMsg.Builder syncMsg = ZhenHuanProto.CrossZhenHuanThirdProcessBanquetScoreNotifyMsg.newBuilder();
        syncMsg.setActivityId(activityId);
        syncMsg.setUserId(userId);
        syncMsg.setAddScore(addScore);
        syncMsg.setScore(totalScore);
        syncMsg.setBanquetId(banquetId);
        MessageHelper.sendPacket(userBaseInfo.getServerId(), userId, YanQuMessageUtils.buildMessage(Protocol.S_ZHENHUAN_THIRD_PROCESS_BANQUET_SCORE_NOTICE_FROM_CROSS, syncMsg));
    }

    /**
     * 宴会结束进程
     * 防止出问题，结算了才能结束进程
     */
    private void banquetEndProcess(CrossZhenHuanThirdProcessBanquetData banquetData) {
        ZhenHuanThirdProcessConfig config = getConfig();
        if (config == null) {
            return;
        }
        if (banquetData == null) {
            return;
        }
        if (banquetData.getBanquetState() != eZhenHuanThirdProcessBanquetStateType.Settle.getValue()) {
            // 宴会未结算
            return;
        }
        long nowTime = System.currentTimeMillis();
        synchronized (getBanquetLock(banquetData.getBanquetId())) {
            if (banquetData.getBanquetState() != eZhenHuanThirdProcessBanquetStateType.Settle.getValue()) {
                // 宴会未结算
                return;
            }
            // 是否达到结束条件
            if (nowTime < banquetData.getStartTime() + config.getEnergyItemTime(banquetData.getOpenItemId()) * DateHelper.SECOND_MILLIONS) {
                return;
            }
            // 结束了
            banquetData.setBanquetState(eZhenHuanThirdProcessBanquetStateType.End.getValue());
        }
    }

    /**
     * 结束的宴会移出内存
     * @param banquetData
     */
    private void banquetRemoveMemory(CrossZhenHuanThirdProcessBanquetData banquetData) {
        // 移出内存
        synchronized (banquetDataMap) {
            banquetDataMap.remove(banquetData.getBanquetId());
        }

        CrossZhenHuanThirdProcessUserData userData = getUserData(banquetData.getUserId());
        if (userData != null) {
            synchronized (getUserLock(banquetData.getUserId())) {
                LinkedList<CrossZhenHuanThirdProcessBanquetData> userBanquetList = userBanquetListMap.get(userData.getUserId());
                if (userBanquetList != null) {
                    userBanquetList.remove(banquetData);
                }
            }
        }
    }

    /**
     * 修bug用
     *
     * @param param 参数
     */
    public void fixBug(String param) {

    }

    /**
     * 调试指令
     *
     * @param userId 用户id
     * @param code   指令
     * @param param  参数
     */
    public void debugByCmd(long userId, String code, String param) {
        if (code.equals("/zh3-init")) {
            initUserData(userId, BigInteger.valueOf(randomHelper.next(1, 10)), BigInteger.valueOf(randomHelper.next(1, 999999)).toString(), System.currentTimeMillis());
        } else if (code.equals("/zh3-method")) {
            // param是方法名 只能调用无参方法
            try {
                // 获取当前实例的类类型
                Class<?> cls = this.getClass();
                // 获取名为param的方法，假设方法无参数
                Method method = cls.getDeclaredMethod(param);
                // 如果该方法是私有的，设置其可访问
                method.setAccessible(true);
                // 调用方法，invoke方法的第一个参数是调用该方法的实例对象，后面是方法参数
                method.invoke(this);
            } catch (Exception e) {
                System.out.println("The method '" + param + "' was not found.");
            }
        } else if (code.equals("/zh3-test")) {
            getAllUserByCmd(1, 1, 0);
        } else if (code.equals("/zh3-npc")) {
            String[] split = param.split("#");
            int banquetId = Integer.parseInt(split[0]);
            CrossZhenHuanThirdProcessBanquetData banquetData = getBanquetData(banquetId);
            if (banquetData == null) {
                return;
            }
            int npcNum = Integer.parseInt(split[1]);
            for (int i = 0; i < npcNum; i++) {
                CrossUserBaseInfo npc = CrossNpcUserMgr.createCrossNpcUserBaseInfo();
                // 加入宴会
                joinBanquet(banquetData.getBanquetId(), banquetData.getUserId(), npc.getUserId());
            }
        }
    }

    /**
     * 拉取参赛列表
     *
     * @param serverId     区服id
     * @param userId       用户id
     * @param targetUserId 请求某个人或者全部传0
     */
    public int getAllUserByCmd(long serverId, long userId, long targetUserId) {
        ZhenHuanProto.ZhenHuanThirdProcessGetAllUserRespMsg.Builder respMsg = ZhenHuanProto.ZhenHuanThirdProcessGetAllUserRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setActivityId(this.activityId);
        List<CrossZhenHuanThirdProcessUserData> userDataList = new ArrayList<>();
        if (targetUserId == 0) {
            // 需要拉所有人
            userDataList = new ArrayList<>(userDataMap.values());
        } else {
            if (userDataMap.containsKey(targetUserId)) {
                userDataList.add(userDataMap.get(targetUserId));
            } else {
                return GameErrorCode.E_ZHENHUAN_THIRD_PROCESS_USER_NOT_FOUND;
            }
        }
        for (CrossZhenHuanThirdProcessUserData userData : userDataList) {
            ZhenHuanProto.ZhenHuanThirdProcessUserTempMsg.Builder userTemp = ZhenHuanProto.ZhenHuanThirdProcessUserTempMsg.newBuilder();
            userTemp.setRank(userData.getPos());
            userTemp.setUserId(userData.getUserId());
            UserBaseInfo userBaseInfo = getUserBaseInfo(userData.getUserId());
            if (userBaseInfo == null) {
                continue;
            }
            userTemp.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            CrossZhenHuanThirdProcessBanquetData banquetData = getUserLastValidOpenBanquet(userData.getUserId());
            if (banquetData == null) {
                userTemp.setUserCount(0);
                userTemp.setStartTime(0);
                userTemp.setCanJoin(false);
                userTemp.setBanquetId(0);
            } else {
                userTemp.setBanquetId(banquetData.getBanquetId());
                userTemp.setUserCount(banquetData.getJoinerMap().size());
                userTemp.setCanJoin(!banquetData.getJoinerMap().containsKey(userId));
                userTemp.setStartTime(banquetData.getStartTime());
            }
            // 开宴数
            userTemp.setBanquetCount(getUserBanquetCount(userData.getUserId()));
            respMsg.addUserList(userTemp);
        }
        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(Protocol.S_ZHENHUAN_THIRD_PROCESS_GET_ALL_USER_FROM_CROSS, respMsg));
        return 0;
    }

    /**
     * 用户开宴数
     *
     * @param userId 用户id
     */
    public int getUserBanquetCount(long userId) {
        CrossZhenHuanThirdProcessUserData userData = this.userDataMap.get(userId);
        if (userData != null) {
            return userData.getBanquetNum();
        }
        return 0;
    }

    /**
     * 返回当前开着的最新的宴会信息
     *
     * @param userId 用户id
     */
    public CrossZhenHuanThirdProcessBanquetData getUserLastValidOpenBanquet(long userId) {
        if (!userBanquetListMap.containsKey(userId)) {
            return null;
        }
        CrossZhenHuanThirdProcessUserData userData = getUserData(userId);
        if (userData == null) {
            return null;
        }
        CrossZhenHuanThirdProcessBanquetData lastBanquetData = null;
        synchronized (getUserLock(userId)) {
            LinkedList<CrossZhenHuanThirdProcessBanquetData> banquetList = userBanquetListMap.get(userId);
            if (banquetList == null || banquetList.isEmpty()) {
                return null;
            }
            lastBanquetData = banquetList.getLast();
        }
        if (isValidBanquet(lastBanquetData)) {
            return lastBanquetData;
        }
        return null;
    }

    /**
     * 获取用户信息数据
     */
    public UserBaseInfo getUserBaseInfo(long userId) {
        CrossUserBaseInfo crossUserBaseInfo = CrossUserMgr.getCrossUserBaseInfo(userId);
        if (crossUserBaseInfo == null) {
            // 找一下npc
            crossUserBaseInfo = CrossNpcUserMgr.getCrossNpcUserBaseInfo(userId);
        }
        if (crossUserBaseInfo == null) {
            return null;
        }
        return crossUserBaseInfo.getUserBaseInfo();
    }

    /**
     * 登录同步玩家活动信息
     *
     * @param serverId
     * @param userId
     */
    public void selfDataSync(long serverId, long userId, boolean isWorship) {
        ZhenHuanProto.ZhenHuanThirdProcessSelfDataSyncMsg.Builder builder = ZhenHuanProto.ZhenHuanThirdProcessSelfDataSyncMsg.newBuilder();
        builder.setActivityId(activityId);
        builder.setAble(this.userDataMap.containsKey(userId));
        builder.setIsWorship(isWorship);
        //参数者基础信息
        for (CrossZhenHuanThirdProcessUserData userData : this.userDataMap.values()) {
            ZhenHuanProto.ZhenHuanThirdProcessSimpleUserTempMsg.Builder userBuilder = ZhenHuanProto.ZhenHuanThirdProcessSimpleUserTempMsg.newBuilder();
            userBuilder.setUserId(userData.getUserId());
            userBuilder.setBanquetCount(this.getUserBanquetCount(userData.getUserId()));
            builder.addUserData(userBuilder);
        }
        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(Protocol.S_ZHENHUAN_THIRD_PROCESS_SELF_DATA_SYNC_FROM_CROSS, builder));
    }
}
